<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta property="og:type" content="website">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="http://example.com/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://example.com"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main">
  
    <article id="post-224.基本计算器" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2021/03/13/224.%E5%9F%BA%E6%9C%AC%E8%AE%A1%E7%AE%97%E5%99%A8/" class="article-date">
  <time class="dt-published" datetime="2021-03-13T14:10:58.566Z" itemprop="datePublished">2021-03-13</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/leetcode/">leetcode</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="p-name article-title" href="/2021/03/13/224.%E5%9F%BA%E6%9C%AC%E8%AE%A1%E7%AE%97%E5%99%A8/">基本计算器</a>
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h3 id="224-基本计算器"><a href="#224-基本计算器" class="headerlink" title="224.基本计算器"></a>224.基本计算器</h3><h4 id="题目描述"><a href="#题目描述" class="headerlink" title="题目描述"></a>题目描述</h4><p>实现一个基本的计算器来计算一个简单的字符串表达式 s 的值。</p>
<h5 id="示例-1："><a href="#示例-1：" class="headerlink" title="示例 1："></a>示例 1：</h5><blockquote>
<p>输入：s = “1 + 1”<br>输出：2</p>
</blockquote>
<h5 id="示例-2："><a href="#示例-2：" class="headerlink" title="示例 2："></a>示例 2：</h5><blockquote>
<p>输入：s = “ 2-1 + 2 “<br>输出：3</p>
</blockquote>
<h5 id="示例-3："><a href="#示例-3：" class="headerlink" title="示例 3："></a>示例 3：</h5><blockquote>
<p>输入：s = “(1+(4+5+2)-3)+(6+8)”<br>输出：23</p>
</blockquote>
<h5 id="提示："><a href="#提示：" class="headerlink" title="提示："></a>提示：</h5><ul>
<li><code>1 &lt;= s.length &lt;= 3 * 105</code></li>
<li><code>s</code> 由数字、<code>&#39;+&#39;</code>、<code>&#39;-&#39;</code>、<code>&#39;(&#39;</code>、<code>&#39;)&#39;</code>、和 <code>&#39; &#39; </code>组成</li>
<li><code>s</code> 表示一个有效的表达式</li>
</ul>
<h4 id="解题思路-amp-踩坑记录"><a href="#解题思路-amp-踩坑记录" class="headerlink" title="解题思路&amp;踩坑记录"></a>解题思路&amp;踩坑记录</h4><h5 id="踩坑1-一定要读清题"><a href="#踩坑1-一定要读清题" class="headerlink" title="踩坑1 一定要读清题"></a>踩坑1 一定要读清题</h5><p>我一开始以为这是要写一个计算器的程序，实现加减乘除的功能，所以把重点放在怎么拆分字符串，并保留加减乘除的分隔符上了，稍微记录一下，用正则表达式<code>re.split()</code>可以添加多个分隔符并决定是否保留某些分隔符。</p>
<h5 id="解题思路1-消去括号"><a href="#解题思路1-消去括号" class="headerlink" title="解题思路1 消去括号"></a>解题思路1 消去括号</h5><p>看清题后，发现题目要求只是做加减法因此可以快速消去括号。用栈来记录去掉括号后的符号变化，用一个指针表示当前位置处的符号。即扫描一遍字符串，遇到空格则略过，遇到+或-更新指针，遇到(添加栈顶符号，遇到)弹出栈顶符号。</p>
<p>代码如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">calculate</span>(<span class="params">self, s: <span class="built_in">str</span></span>) -&gt; int:</span></span><br><span class="line">        <span class="comment"># 扫描字符，遇到+或-时更新栈顶符号，遇到（或)时也更新栈顶符号</span></span><br><span class="line">        ops = [<span class="number">1</span>]</span><br><span class="line">        sign = <span class="number">1</span></span><br><span class="line">        res = <span class="number">0</span></span><br><span class="line">        i = <span class="number">0</span></span><br><span class="line">        <span class="keyword">while</span> i &lt; <span class="built_in">len</span>(s):</span><br><span class="line">            <span class="keyword">if</span> s[i] == <span class="string">&quot; &quot;</span>:</span><br><span class="line">                i += <span class="number">1</span></span><br><span class="line">            <span class="keyword">elif</span> s[i] == <span class="string">&quot;(&quot;</span>:</span><br><span class="line">                ops.insert(<span class="number">0</span>, sign)</span><br><span class="line">                i += <span class="number">1</span></span><br><span class="line">            <span class="keyword">elif</span> s[i] == <span class="string">&quot;)&quot;</span>:</span><br><span class="line">                ops.pop(<span class="number">0</span>)</span><br><span class="line">                i += <span class="number">1</span></span><br><span class="line">            <span class="keyword">elif</span> s[i] == <span class="string">&quot;+&quot;</span>:</span><br><span class="line">                sign = ops[<span class="number">0</span>]</span><br><span class="line">                i += <span class="number">1</span></span><br><span class="line">            <span class="keyword">elif</span> s[i] == <span class="string">&quot;-&quot;</span>:</span><br><span class="line">                sign = -ops[<span class="number">0</span>]</span><br><span class="line">                i += <span class="number">1</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                num = <span class="number">0</span></span><br><span class="line">                <span class="keyword">while</span> i &lt; <span class="built_in">len</span>(s) <span class="keyword">and</span> s[i].isdigit():</span><br><span class="line">                    num = num*<span class="number">10</span> + <span class="built_in">int</span>(s[i])</span><br><span class="line">                    i += <span class="number">1</span></span><br><span class="line">                res += sign * num</span><br><span class="line">        <span class="keyword">return</span> res</span><br></pre></td></tr></table></figure>

<h5 id="踩坑记录二-判断字符是否为数字"><a href="#踩坑记录二-判断字符是否为数字" class="headerlink" title="踩坑记录二 判断字符是否为数字"></a>踩坑记录二 判断字符是否为数字</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span> i &lt; <span class="built_in">len</span>(s) <span class="keyword">and</span> s[i].isdigit():</span><br></pre></td></tr></table></figure>

<p>这句话中，用到<code>isdigit()</code>这个判断方法，不能直接用<code>int(s[i])</code>否则会报错</p>
<h5 id="踩坑记录三-循环时用while循环而不是for循环"><a href="#踩坑记录三-循环时用while循环而不是for循环" class="headerlink" title="踩坑记录三 循环时用while循环而不是for循环"></a>踩坑记录三 循环时用<code>while</code>循环而不是<code>for</code>循环</h5><p>在遍历整个字符串时，如果采用<code>for</code>循环则会这样：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(s)):</span><br><span class="line">	i +=<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p>如果在循环内多次出现<code>i+=1</code>时，下一次循环还是会从上一个循环的i加上1之后开始，并不会因为循环内的i值改变而变化，因此这里需要使用while循环。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2021/03/13/224.%E5%9F%BA%E6%9C%AC%E8%AE%A1%E7%AE%97%E5%99%A8/" data-id="ckm7t5pcc0000hott4dzwhooy" data-title="基本计算器" class="article-share-link">Share</a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" rel="tag">学习笔记</a></li></ul>

    </footer>
  </div>
  
</article>



  
    <article id="post-django自定义日志" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2021/03/13/django%E8%87%AA%E5%AE%9A%E4%B9%89%E6%97%A5%E5%BF%97/" class="article-date">
  <time class="dt-published" datetime="2021-03-13T14:09:56.894Z" itemprop="datePublished">2021-03-13</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/django/">django</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="p-name article-title" href="/2021/03/13/django%E8%87%AA%E5%AE%9A%E4%B9%89%E6%97%A5%E5%BF%97/">django自定义日志</a>
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <p>日志模块需要配置4个部分</p>
<h4 id="1-loggers"><a href="#1-loggers" class="headerlink" title="1 loggers"></a>1 loggers</h4><p>logger是日志的入口，可以配置日志的级别，描述该logger可以处理的日志的严重程度。每一条写入logger的消息就是一条日志记录，每一条日志记录也包含日志级别，当logger处理一条消息时，会将自身级别与该条日志的级别做对比，如果该条日志的级别等于或高于logger的级别，那么就会被进一步处理，否则该条日志就会被忽略。当logger确定处理一条日志后，会把它传给handler。日志级别定义如下：</p>
<ul>
<li><code>DEBUG</code>：排查故障时使用的低级别系统信息</li>
<li><code>INFO</code>：一般的系统信息</li>
<li><code>WARNING</code>：描述系统发生了一些小问题的信息</li>
<li><code>ERROR</code>：描述系统发生了大问题的信息</li>
<li><code>CRITICAL</code>：描述系统发生严重问题的信息</li>
</ul>
<h4 id="2-handlers"><a href="#2-handlers" class="headerlink" title="2 handlers"></a>2 handlers</h4><p>handler是决定如何处理logger中每一条消息的引擎。它描述特定的日志行为，把消息输出到屏幕、文件或者网络socket。handler也有日志级别的概念，如果一条日志记录的级别不匹配或低于handler的日志级别，对应的消息就会被handler忽略。一个logger可以有多个handler，每一个handler可以有不同的日志级别。这样就可以根据消息重要性的不同来提供不同格式的输出。handlers可以配置如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">LOGGING = &#123;</span><br><span class="line">	...</span><br><span class="line">    <span class="string">&#x27;handlers&#x27;</span>: &#123;</span><br><span class="line">        <span class="string">&#x27;console&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;level&#x27;</span>: <span class="string">&#x27;INFO&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;filters&#x27;</span>: [<span class="string">&#x27;require_debug_true&#x27;</span>],</span><br><span class="line">            <span class="string">&#x27;class&#x27;</span>: <span class="string">&#x27;logging.StreamHandler&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;formatter&#x27;</span>: <span class="string">&#x27;simple&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="string">&#x27;mail_admins&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;level&#x27;</span>: <span class="string">&#x27;ERROR&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;class&#x27;</span>: <span class="string">&#x27;django.utils.log.AdminEmailHandler&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;filters&#x27;</span>: [<span class="string">&#x27;special&#x27;</span>]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>可以在‘hanlers’中添加自定义的handler。handler各参数定义如下:</p>
<table>
<thead>
<tr>
<th>参数名称</th>
<th>定义</th>
</tr>
</thead>
<tbody><tr>
<td>level</td>
<td>定义该handler可以匹配的日志级别</td>
</tr>
<tr>
<td>class</td>
<td>指定使用哪个类，python中提供了多个handlers的类，自定义时也可以继承这些类进行相应的修改。<br />StreamHandler，位于logging.StreamHandler。将日志信息输出到sys.stout, sys.stderr或者类文件对象，只有一个参数<code>class logging.StreamHandler(stream=None)</code>，如果<code>stream</code>为空则默认输出到sys.stderr上。<br />FileHandler，位于logging.FileHandler。继承StreamHandler，将日志信息输出到磁盘文件上。参数如下：<code>class logging.FileHandler(filename, mode=&#39;a&#39;, encoding=None, delay=False)</code>，<br />除此之外，还有NullHandler、WatchedFileHandler、RotatingFileHandler、TimedRotatingFileHandler、SocketHandler、DatagramHandler、SysLogHandler、NtEventHandler、SMTPHandler、MemoryHandler、HTTPHandler等等，具体可以参考python的官方文档<a target="_blank" rel="noopener" href="https://docs.python.org/3.8/library/logging.handlers.html">https://docs.python.org/3.8/library/logging.handlers.html</a></td>
</tr>
<tr>
<td>filters</td>
<td>指定过滤器</td>
</tr>
<tr>
<td>formatter</td>
<td>指定日志格式</td>
</tr>
<tr>
<td>其他参数</td>
<td>handler类中需要指定的参数，例如’filename’,’encoding’等</td>
</tr>
</tbody></table>
<h4 id="3-filters"><a href="#3-filters" class="headerlink" title="3 filters"></a>3 filters</h4><p>在日志记录从logger传到handler的过程中，可以使用filter来做额外的控制。</p>
<p>默认情况下，只要级别匹配，任何日志消息都会被处理。不过也可以通过filter来给日志处理增加额外的条件，例如可以添加一个filter只允许某个特定来源的ERROR消息输出。filter在django中的定义格式如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">LOGGING = &#123;</span><br><span class="line">	...</span><br><span class="line">    <span class="string">&#x27;filters&#x27;</span>: &#123;</span><br><span class="line">        <span class="string">&#x27;special&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;()&#x27;</span>: <span class="string">&#x27;optimize.filters.SpecialFilter&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;foo&#x27;</span>: <span class="string">&#x27;bar&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="string">&#x27;require_debug_true&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;()&#x27;</span>: <span class="string">&#x27;django.utils.log.RequireDebugTrue&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>filters</code>里面可以定义多个过滤器，<code>()</code>后面跟的时过滤器类的位置，过滤器类内容如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RequireDebugFalse</span>(<span class="params">logging.Filter</span>):</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">filter</span>(<span class="params">self, record</span>):</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">not</span> settings.DEBUG</span><br></pre></td></tr></table></figure>

<p>自定义的过滤器类也只需要重写以下<code>filter</code>方法即可，这个方法只会返回<code>True</code>或<code>False</code>，返回<code>False</code>时不处理，返回<code>True</code>时会过滤掉此条日志。</p>
<h4 id="4-格式器formatter"><a href="#4-格式器formatter" class="headerlink" title="4 格式器formatter"></a>4 格式器formatter</h4><p>格式器用来规定每条日志的格式，一个格式器通常由包含LogRecord attributes的python格式化字符串组成，也可以自行配置特定合适的格式器。LogRecord attributes包含以下内容</p>
<table>
<thead>
<tr>
<th align="left">Attribute name</th>
<th align="left">Format</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody><tr>
<td align="left">args</td>
<td align="left">You shouldn’t need to format this yourself.</td>
<td align="left">The tuple of arguments merged into <code>msg</code> to produce <code>message</code>, or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary).</td>
</tr>
<tr>
<td align="left">asctime</td>
<td align="left"><code>%(asctime)s</code></td>
<td align="left">Human-readable time when the <a target="_blank" rel="noopener" href="https://docs.python.org/3/library/logging.html#logging.LogRecord"><code>LogRecord</code></a> was created. By default this is of the form ‘2003-07-08 16:49:45,896’ (the numbers after the comma are millisecond portion of the time).</td>
</tr>
<tr>
<td align="left">created</td>
<td align="left"><code>%(created)f</code></td>
<td align="left">Time when the <a target="_blank" rel="noopener" href="https://docs.python.org/3/library/logging.html#logging.LogRecord"><code>LogRecord</code></a> was created (as returned by <a target="_blank" rel="noopener" href="https://docs.python.org/3/library/time.html#time.time"><code>time.time()</code></a>).</td>
</tr>
<tr>
<td align="left">exc_info</td>
<td align="left">You shouldn’t need to format this yourself.</td>
<td align="left">Exception tuple (à la <code>sys.exc_info</code>) or, if no exception has occurred, <code>None</code>.</td>
</tr>
<tr>
<td align="left">filename</td>
<td align="left"><code>%(filename)s</code></td>
<td align="left">Filename portion of <code>pathname</code>.</td>
</tr>
<tr>
<td align="left">funcName</td>
<td align="left"><code>%(funcName)s</code></td>
<td align="left">Name of function containing the logging call.</td>
</tr>
<tr>
<td align="left">levelname</td>
<td align="left"><code>%(levelname)s</code></td>
<td align="left">Text logging level for the message (<code>&#39;DEBUG&#39;</code>, <code>&#39;INFO&#39;</code>, <code>&#39;WARNING&#39;</code>, <code>&#39;ERROR&#39;</code>, <code>&#39;CRITICAL&#39;</code>).</td>
</tr>
<tr>
<td align="left">levelno</td>
<td align="left"><code>%(levelno)s</code></td>
<td align="left">Numeric logging level for the message (<code>DEBUG</code>, <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>, <code>CRITICAL</code>).</td>
</tr>
<tr>
<td align="left">lineno</td>
<td align="left"><code>%(lineno)d</code></td>
<td align="left">Source line number where the logging call was issued (if available).</td>
</tr>
<tr>
<td align="left">message</td>
<td align="left"><code>%(message)s</code></td>
<td align="left">The logged message, computed as <code>msg % args</code>. This is set when <a target="_blank" rel="noopener" href="https://docs.python.org/3/library/logging.html#logging.Formatter.format"><code>Formatter.format()</code></a> is invoked.</td>
</tr>
<tr>
<td align="left">module</td>
<td align="left"><code>%(module)s</code></td>
<td align="left">Module (name portion of <code>filename</code>).</td>
</tr>
<tr>
<td align="left">msecs</td>
<td align="left"><code>%(msecs)d</code></td>
<td align="left">Millisecond portion of the time when the <a target="_blank" rel="noopener" href="https://docs.python.org/3/library/logging.html#logging.LogRecord"><code>LogRecord</code></a> was created.</td>
</tr>
<tr>
<td align="left">msg</td>
<td align="left">You shouldn’t need to format this yourself.</td>
<td align="left">The format string passed in the original logging call. Merged with <code>args</code> to produce <code>message</code>, or an arbitrary object (see <a target="_blank" rel="noopener" href="https://docs.python.org/3/howto/logging.html#arbitrary-object-messages">Using arbitrary objects as messages</a>).</td>
</tr>
<tr>
<td align="left">name</td>
<td align="left"><code>%(name)s</code></td>
<td align="left">Name of the logger used to log the call.</td>
</tr>
<tr>
<td align="left">pathname</td>
<td align="left"><code>%(pathname)s</code></td>
<td align="left">Full pathname of the source file where the logging call was issued (if available).</td>
</tr>
<tr>
<td align="left">process</td>
<td align="left"><code>%(process)d</code></td>
<td align="left">Process ID (if available).</td>
</tr>
<tr>
<td align="left">processName</td>
<td align="left"><code>%(processName)s</code></td>
<td align="left">Process name (if available).</td>
</tr>
<tr>
<td align="left">relativeCreated</td>
<td align="left"><code>%(relativeCreated)d</code></td>
<td align="left">Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.</td>
</tr>
<tr>
<td align="left">stack_info</td>
<td align="left">You shouldn’t need to format this yourself.</td>
<td align="left">Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record.</td>
</tr>
<tr>
<td align="left">thread</td>
<td align="left"><code>%(thread)d</code></td>
<td align="left">Thread ID (if available).</td>
</tr>
<tr>
<td align="left">threadName</td>
<td align="left"><code>%(threadName)s</code></td>
<td align="left">Thread name (if available).</td>
</tr>
</tbody></table>
<p>配置formatter时，可以采用下列形式，在setting.py中添加</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">LOGGING = &#123;</span><br><span class="line">	...</span><br><span class="line">    <span class="string">&#x27;formatters&#x27;</span>: &#123;</span><br><span class="line">        <span class="string">&#x27;verbose&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;format&#x27;</span>: <span class="string">&#x27;&#123;levelname&#125; &#123;asctime&#125; &#123;module&#125; &#123;process:d&#125; &#123;thread:d&#125; &#123;message&#125;&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;style&#x27;</span>: <span class="string">&#x27;&#123;&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="string">&#x27;simple&#x27;</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;format&#x27;</span>: <span class="string">&#x27;&#123;levelname&#125; &#123;message&#125;&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;style&#x27;</span>: <span class="string">&#x27;&#123;&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>




      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2021/03/13/django%E8%87%AA%E5%AE%9A%E4%B9%89%E6%97%A5%E5%BF%97/" data-id="ckm7t5pcx0002hott7qcee3bc" data-title="django自定义日志" class="article-share-link">Share</a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" rel="tag">学习笔记</a></li></ul>

    </footer>
  </div>
  
</article>



  
    <article id="post-sqlldr导入大量数据到oracle数据库" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2021/03/13/sqlldr%E5%AF%BC%E5%85%A5%E5%A4%A7%E9%87%8F%E6%95%B0%E6%8D%AE%E5%88%B0oracle%E6%95%B0%E6%8D%AE%E5%BA%93/" class="article-date">
  <time class="dt-published" datetime="2021-03-13T14:09:39.460Z" itemprop="datePublished">2021-03-13</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/oracle/">oracle</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="p-name article-title" href="/2021/03/13/sqlldr%E5%AF%BC%E5%85%A5%E5%A4%A7%E9%87%8F%E6%95%B0%E6%8D%AE%E5%88%B0oracle%E6%95%B0%E6%8D%AE%E5%BA%93/">使用sqlldr导入上亿条数据到oracle中</a>
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <p>接到一个任务，要把160G的数据导入到公司oracle服务器上。最开始以为就是导数据这么简单的任务，虽然没以前没用过oracle没导过数据，但是在网上搜一下方法不久行了？我信心满满地接了下来，没想到这么简单的任务也有如此多的坑，下面把导数据过程中的踩坑和弯路记录下来，共勉。</p>
<p>第一步当然是选择用啥工具导入数据库，常用的navicat或pl/sql感觉速度上都不太行，在网上看到导入大量数据一般用sqlloader这个oracle自带的工具。sqlloader就是sqlldr，在oracle官网上可以下载客户端。下载地址：<a target="_blank" rel="noopener" href="https://www.oracle.com/cn/database/technologies/instant-client/winx64-64-downloads.html%E3%80%82">https://www.oracle.com/cn/database/technologies/instant-client/winx64-64-downloads.html。</a></p>
<p><strong>踩坑1</strong>：找不到对应版本的sqlloader。公司服务器的oracle版本是11g，然而11g的版本在官网上并没有sqlloader。网上好多博客说精简版客户端没有sqlloader，但是在哪找非精简版的客户端呢？还好在参考了</p>
<p>的内容，高版本的sqlloader同样支持11g的oracle服务器版。于是下载了12.2.0.1.0版本的sqlloader，下载地址：<a target="_blank" rel="noopener" href="https://www.oracle.com/cn/database/technologies/instant-client/winx64-64-downloads.html#license-lightbox%E3%80%82">https://www.oracle.com/cn/database/technologies/instant-client/winx64-64-downloads.html#license-lightbox。</a></p>
<p><strong>踩坑2</strong>：下载后解压，把解压后的路径加到环境变量中，即可在cmd命令行中测试sqlldr是否正常工作。但是我在cmd命令行中测试sqlldr总是报这样的错误：无法定位程序输入点域动态连接库上。这个错误是sqlldr和原有的oracle client版本不一致造成的。我电脑之前安装的是instantclient-basic-windows.x64-11.2.0.4.0。于是卸载之前版本的basic客户端，安装instantclient-basic-windows.x64-12.2.0.1.0。终于，sqlldr的环境搞定了！测试页面如下：</p>
<p><img src="C:\Users\Anyon\AppData\Roaming\Typora\typora-user-images\image-20210204170041753.png" alt="image-20210204170041753"></p>
<p><strong>踩坑3</strong>：sqlldr的环境搞定后，下一步就是连接数据库了。由于oracle数据库安装在服务器上，所以连接的语法是，在命令行输入：</p>
<p><code>sqlldr username/password@host:port/service_name</code></p>
<p>注意<code>sqlldr</code>后面跟的是主机字符串，而主机字符串最后一项得是service_name而不是SID。我总觉得用SID也是可以连接的，但是没找到相应的连接语句。</p>
<p><strong>踩坑4</strong>：如果能正常连接，下一步需要指定控制文件，也就是control文件。当然也可以和上一步命令一起输入。control文件是sqlldr最为重要的一个文件，它指定了加载选项，加载数据的内容，加载方式等。control文件写的好，后面就一点坑都不用踩！！新建一个后缀为.ctl的文件作为控制文件，例：data.ctl，内容如下</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">OPTIONS (<span class="keyword">skip</span><span class="operator">=</span><span class="number">1</span>)  <span class="comment">--control文件中，--是注释符，options可以指定关键字的默认值，有效的关键字可以通过在命令行中输入sqlldr查看，常用的有skip,rows,direct等</span></span><br><span class="line">LODA DATA <span class="comment">--加载数据</span></span><br><span class="line">INFILE &quot;data1.csv&quot;  <span class="comment">--INFILE关键字指定从哪些文件中加载数据，可以只写一个文件，如果从多个文件加载的话就多写几行</span></span><br><span class="line">INFILE &quot;data2.csv&quot;</span><br><span class="line">INFILE &quot;data3.csv&quot;</span><br><span class="line"><span class="keyword">TRUNCATE</span>  <span class="comment">--先把表清空</span></span><br><span class="line"><span class="keyword">INTO</span> <span class="keyword">TABLE</span> DATA  <span class="comment">--往DATA表中插入数据</span></span><br><span class="line">Field terminated <span class="keyword">by</span> &quot;,&quot;  <span class="comment">--字段以，（逗号）隔开，因为是从csv文件中导入的，csv文件是以逗号分隔的文本文件</span></span><br><span class="line">Optionally enclosed <span class="keyword">by</span> <span class="string">&#x27;&quot;&#x27;</span>  <span class="comment">--数据中每个字段用&quot;框起，这个地方非常重要。我最开始以为有了上一行字段以逗号分开后就不用这句话了，后来才发现我还是太年轻</span></span><br><span class="line"><span class="keyword">trailing</span> nullcols  <span class="comment">--没有内容的字段记为空</span></span><br><span class="line">(</span><br><span class="line">字段<span class="number">1</span>，  <span class="comment">--最后一个字段不用加逗号，如果对应数据库中的字段类型是date，则需要用函数DATE转化成对应的格式</span></span><br><span class="line">字段<span class="number">2</span>，</span><br><span class="line">字段<span class="number">3</span> <span class="type">DATE</span> <span class="string">&#x27;YYYY/MM/DD HH24:MI:SS&#x27;</span>,</span><br><span class="line">...</span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<p><strong>弯路1</strong>: 如果一开始就按照上述的格式编写控制文件，就不会有任何问题。但是我自作聪明把<code>Optionally enclosed by &#39;&quot;&#39;</code>这句话删掉了。原始数据是csv格式的，其中每个文件的大小在15G左右，因此我先用pandas导出了前1000行保存到了<code>data1000.csv</code>中，看看数据长啥样。每一行的格式都是和数据库中的一样，看样子没啥问题。于是在命令行中输入</p>
<p><code>sqlldr username/password@host:port/service_name control=data.ctl</code></p>
<p>其中控制文件中指定了从<code>data1000.csv</code>文件加载数据。不出意外的报错了，原因是pandas导出数据时，自动加上了一列行索引，于是sqlldr加载数据时字段没对应上。这种情况对应着csv文件中的列数多余数据库表中的列数，需要在多余的列对应位置加上 FILLER关键字进行跳过，如下：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">字段<span class="number">1</span>，</span><br><span class="line">virtual_column FILLER  <span class="comment">--跳过这一列</span></span><br><span class="line">字段<span class="number">2</span>，</span><br></pre></td></tr></table></figure>

<p>跳过索引列之后，从pandas导出的这1000行数据就能正常上传了！！</p>
<p>于是在控制文件中指定加载源文件，在命令行执行后又又又报错了！查看日志，报如下错误：</p>
<blockquote>
<p>记录 1: 被拒绝 - 表 DATA 的列 ID 出现错误。 </p>
<p>ORA-01722: 无效数字</p>
</blockquote>
<p>这个报错的原因是从csv文件中读出来的字段都是字符串，而ID这个字段的类型是Number，所以类型不匹配造成的。那为啥用pandas导出的前1000行数据就可以正常加载呢？原因是pandas在导出数据是自动做了转换，把数字构成的字符串保存成了字符串格式。那我在控制文件中指定一下字段类型是不是也一样的效果哈哈哈，我试了以下格式的控制文件：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ID Number(<span class="number">16</span>)</span><br></pre></td></tr></table></figure>

<p>然后还是报错，结果如下：</p>
<blockquote>
<p>SQL*Loader-350: Syntax error at line 9. Expecting “,” or “)”, found “NUMBER”. ID NUMBER(16),</p>
</blockquote>
<p>为什么字段后面能写DATE类型的格式，不能写Number呢，这是因为DATE是sqlldr中的一个转换函数，而Number不是。有许多博客建议在该字段后面加上整数的关键字：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ID <span class="type">INTEGER</span>  <span class="comment">--表示插入的数据是二进制</span></span><br><span class="line"><span class="comment">-- 或者</span></span><br><span class="line">ID <span class="type">INTEGER</span> <span class="keyword">EXTERNAL</span> <span class="comment">--表示插入的数据是string（这个地方我还是有疑惑）</span></span><br></pre></td></tr></table></figure>

<p>我试了上面的两种写法，还是报ORA-01722的错。在百思不得其解的情况下我突然萌生了一个笨办法，既然用pandas导出的前1000行记录能插入，索性我就把所有的源数据都用pandas转换一下，不就可以导入了吗？说干就干，立马写了一个python脚本，丢在电脑上执行了一晚上。</p>
<p><strong>弯路2</strong>: 好不容易用pandas把所有数据都转换完成了，这个时候又出现了新的问题！某些源数据中字段是中文，编码格式得用GB2312；有些字段中还有换行符，pandas导出时会出现把一行数据导出为2行的情况。我这个弯路越走越弯了啊。于是我又写了一个转换判断字段中是否存在换行符的脚本，把含有换行符的几个源文件再转换一遍。</p>
<p><strong>踩坑5</strong>: 对于不含中文且字段中没有换行符的文件，经过pandas转换后已经可以上传到服务器了！赶紧执行上传命令</p>
<p><code>sqlldr username/password@host:port/service_name control=data.ctl</code></p>
<p>这个转换后的数据文件有32G，我就眼睁睁看着它以大概250万条/小时的速度导入，这导到猴年马月。</p>
<p><strong>最终解决办法</strong>:  在踩过了前面的坑和弯路后，我忽然发现控制文件中<code>Optionally enclosed by &#39;&quot;&#39;</code>似乎有奇妙的作用，加上这句话之后，那些被双引号括起来的数字就可以被当作数字接收而不是被当作字符串拒绝了！这么说我用pandas转换文件完全是多次一举？？并且以打开直接路径加载的方式要上面的加载方式快的多！所以最终控制文件的内容如下：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">OPTIONS (direct<span class="operator">=</span><span class="literal">true</span>, <span class="keyword">skip</span><span class="operator">=</span><span class="number">1</span>, BINDSIZE<span class="operator">=</span><span class="number">20971520</span>,READSIZE<span class="operator">=</span><span class="number">20971520</span>,<span class="keyword">ROWS</span><span class="operator">=</span><span class="number">500000</span>)  <span class="comment">--control文件中，--是注释符，options可以指定关键字的默认值，有效的关键字可以通过在命令行中输入sqlldr查看，常用的有skip,rows,direct等。direct=true就是指以直接路径加载</span></span><br><span class="line">LODA DATA <span class="comment">--加载数据</span></span><br><span class="line">INFILE &quot;data1.csv&quot;  <span class="comment">--INFILE关键字指定从哪些文件中加载数据，可以只写一个文件，如果从多个文件加载的话就多写几行</span></span><br><span class="line">INFILE &quot;data2.csv&quot;</span><br><span class="line">INFILE &quot;data3.csv&quot;</span><br><span class="line"><span class="keyword">TRUNCATE</span>  <span class="comment">--先把表清空</span></span><br><span class="line"><span class="keyword">INTO</span> <span class="keyword">TABLE</span> DATA  <span class="comment">--往DATA表中插入数据</span></span><br><span class="line">Field terminated <span class="keyword">by</span> &quot;,&quot;  <span class="comment">--字段以，（逗号）隔开，因为是从csv文件中导入的，csv文件是以逗号分隔的文本文件</span></span><br><span class="line">Optionally enclosed <span class="keyword">by</span> <span class="string">&#x27;&quot;&#x27;</span>  <span class="comment">--数据中每个字段用&quot;框起，这个地方非常重要。</span></span><br><span class="line"><span class="keyword">trailing</span> nullcols  <span class="comment">--没有内容的字段记为空</span></span><br><span class="line">(</span><br><span class="line">字段<span class="number">1</span>，  <span class="comment">--最后一个字段不用加逗号，如果对应数据库中的字段类型是date，则需要用函数DATE转化成对应的格式</span></span><br><span class="line">字段<span class="number">2</span>，</span><br><span class="line">字段<span class="number">3</span> <span class="type">DATE</span> <span class="string">&#x27;YYYY/MM/DD HH24:MI:SS&#x27;</span>,</span><br><span class="line">...</span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<p>这种直接路径加载的方式也可选择并行，需要把<code>TRUNCATE</code>改为<code>APPEND</code>。不过我没有用并行的方式，一个多小时就插入完了所有数据。一张表有1.78亿条记录，这个速度已经很可以了。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2021/03/13/sqlldr%E5%AF%BC%E5%85%A5%E5%A4%A7%E9%87%8F%E6%95%B0%E6%8D%AE%E5%88%B0oracle%E6%95%B0%E6%8D%AE%E5%BA%93/" data-id="ckm7t5pct0001hottg9kc6k5h" data-title="使用sqlldr导入上亿条数据到oracle中" class="article-share-link">Share</a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" rel="tag">学习笔记</a></li></ul>

    </footer>
  </div>
  
</article>



  
    <article id="post-windows环境下安装pyscipopt" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2021/03/13/windows%E7%8E%AF%E5%A2%83%E4%B8%8B%E5%AE%89%E8%A3%85pyscipopt/" class="article-date">
  <time class="dt-published" datetime="2021-03-13T14:09:39.436Z" itemprop="datePublished">2021-03-13</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/SCIP/">SCIP</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="p-name article-title" href="/2021/03/13/windows%E7%8E%AF%E5%A2%83%E4%B8%8B%E5%AE%89%E8%A3%85pyscipopt/">windows下安装pyscipopy</a>
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <p>SCIP是一款优秀的开源求解器，起源于ZIB(Zuse Institute Berlin)，由博士生Tobias Achterberg奠定整个框架。在开源求解器中，它对混合整数规划和混合整数非线性规划问题求解速度是最快的之一。 在使用SCIP的过程中，用户可以对求解过程进行全面控制，访问详细的求解过程直到最终的结果。</p>
<p>SCIP支持多种编程语言，包括：</p>
<blockquote>
<p>Python</p>
<p>Java</p>
<p>AMPL</p>
<p>GAMS</p>
<p>MATLAB</p>
</blockquote>
<p>也支持多种平台，包括</p>
<blockquote>
<p>Linux</p>
<p>Mac</p>
<p>Windows</p>
<p>SunOS</p>
<p>Andriod</p>
</blockquote>
<p>本文介绍在Windows环境中安装SCIPOptSuite，以及安装python调用接口的方法。</p>
<h3 id="一、安装SCIPOptSuite"><a href="#一、安装SCIPOptSuite" class="headerlink" title="一、安装SCIPOptSuite"></a>一、安装SCIPOptSuite</h3><p>1、在官网下载安装包，地址<a target="_blank" rel="noopener" href="https://www.scipopt.org/index.php#download">https://www.scipopt.org/index.php#do</a>wnload</p>
<p><img src="D:\01_work\2021\01_document\05其他\技术博客\file-read-667.png" alt="file-read-667"></p>
<p>注意它需要哪些版本的Visual C++依赖，后面很可能会用到。<br>2.下载完后，管理员安装即可。</p>
<p>3.记得设置境变量，把 ..\SCIPOptSuite 6.0.2\bin加到环境变量中去。</p>
<p>4.测试一下。打开cmd，输入scip，显示下面画面即可证明安装成功。</p>
<p><img src="D:\01_work\2021\01_document\05其他\技术博客\file-read-668.png" alt="file-read-668"></p>
<h3 id="二、安装pyscipopt包"><a href="#二、安装pyscipopt包" class="headerlink" title="二、安装pyscipopt包"></a>二、安装pyscipopt包</h3><p>1、python通过pyscipopt包来调用安装好的SCIPOptSuite，首先要注意pyscipopt的版本是否和SCIPOptSuite的版本匹配，匹配关系见<a target="_blank" rel="noopener" href="https://github.com/SCIP-Interfaces/PySCIPOpt/blob/master/INSTALL.md%E3%80%82">https://github.com/SCIP-Interfaces/PySCIPOpt/blob/master/INSTALL.md。</a></p>
<table>
<thead>
<tr>
<th align="left">SCIP</th>
<th align="left">PySCIPOpt</th>
</tr>
</thead>
<tbody><tr>
<td align="left">7.0</td>
<td align="left">3.0</td>
</tr>
<tr>
<td align="left">6.0</td>
<td align="left">2.2, 2.1, 2.0</td>
</tr>
<tr>
<td align="left">5.0</td>
<td align="left">1.4, 1.3</td>
</tr>
<tr>
<td align="left">4.0</td>
<td align="left">1.2, 1.1</td>
</tr>
<tr>
<td align="left">3.2</td>
<td align="left">1.0</td>
</tr>
</tbody></table>
<p>2、确认版本后，在anaconda中通过以下命令安装pyscipopt</p>
<p>pip install pyscipopt==版本号</p>
<p>3、如果安装失败，出现以下错误：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ImportError: DLL load failed: 找不到指定的模块。</span><br></pre></td></tr></table></figure>

<p>请检查版本号是否正确。</p>
<p>如果出现以下错误：</p>
<blockquote>
<p>Microsoft visual C++ 14.0 is required.</p>
</blockquote>
<p>请安装相应的微软环境依赖。</p>
<p>4、安装后，在python环境中输入 import pyscipopt 不报错即证明安装成功！</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2021/03/13/windows%E7%8E%AF%E5%A2%83%E4%B8%8B%E5%AE%89%E8%A3%85pyscipopt/" data-id="ckm7t5pcy0003hott7agthxjt" data-title="windows下安装pyscipopy" class="article-share-link">Share</a>
      
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" rel="tag">学习笔记</a></li></ul>

    </footer>
  </div>
  
</article>



  
    <article id="post-hello-world" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2021/03/13/hello-world/" class="article-date">
  <time class="dt-published" datetime="2021-03-13T13:41:14.112Z" itemprop="datePublished">2021-03-13</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="p-name article-title" href="/2021/03/13/hello-world/">Hello World</a>
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <p>Welcome to <a target="_blank" rel="noopener" href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a target="_blank" rel="noopener" href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a target="_blank" rel="noopener" href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a target="_blank" rel="noopener" href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p>
<h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">&quot;My New Post&quot;</span></span><br></pre></td></tr></table></figure>

<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/writing.html">Writing</a></p>
<h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure>

<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/server.html">Server</a></p>
<h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure>

<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/generating.html">Generating</a></p>
<h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure>

<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2021/03/13/hello-world/" data-id="ckm7sazck0000mgttazci8600" data-title="Hello World" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  


</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/SCIP/">SCIP</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/django/">django</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/leetcode/">leetcode</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/oracle/">oracle</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" rel="tag">学习笔记</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" style="font-size: 10px;">学习笔记</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/03/">March 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/03/13/224.%E5%9F%BA%E6%9C%AC%E8%AE%A1%E7%AE%97%E5%99%A8/">基本计算器</a>
          </li>
        
          <li>
            <a href="/2021/03/13/django%E8%87%AA%E5%AE%9A%E4%B9%89%E6%97%A5%E5%BF%97/">django自定义日志</a>
          </li>
        
          <li>
            <a href="/2021/03/13/sqlldr%E5%AF%BC%E5%85%A5%E5%A4%A7%E9%87%8F%E6%95%B0%E6%8D%AE%E5%88%B0oracle%E6%95%B0%E6%8D%AE%E5%BA%93/">使用sqlldr导入上亿条数据到oracle中</a>
          </li>
        
          <li>
            <a href="/2021/03/13/windows%E7%8E%AF%E5%A2%83%E4%B8%8B%E5%AE%89%E8%A3%85pyscipopt/">windows下安装pyscipopy</a>
          </li>
        
          <li>
            <a href="/2021/03/13/hello-world/">Hello World</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2021 John Doe<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/js/jquery-3.4.1.min.js"></script>



  
<script src="/fancybox/jquery.fancybox.min.js"></script>




<script src="/js/script.js"></script>





  </div>
</body>
</html>